package com.dynabook.ems.model.listener;

import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.exception.ExcelDataConvertException;
import cn.idev.excel.read.listener.ReadListener;
import com.dynabook.ems.disruptor.Excel.EmsDisruptorProducer;
import com.dynabook.ems.model.dto.EmsDataDTO;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

@Slf4j
public class EmsDataListener implements ReadListener<EmsDataDTO> {

    private EmsDisruptorProducer emsDisruptorProducer;

    public EmsDataListener(EmsDisruptorProducer emsDisruptorProducer) {
        this.emsDisruptorProducer = emsDisruptorProducer;
    }

    // 缓存数据用于批量处理
    private final List<EmsDataDTO> buffer = new ArrayList<>();
    private static final int BATCH_SIZE = 1000;

    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        log.error("解析失败，但是继续解析下一行:{}", exception.getMessage());
        if (exception instanceof ExcelDataConvertException) {
            ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
            log.error("第{}行，第{}列解析异常，数据为:{}", excelDataConvertException.getRowIndex(),
                    excelDataConvertException.getColumnIndex(), excelDataConvertException.getCellData());
        }
        if (exception instanceof NullPointerException) {
            ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
            log.error("第{}行，第{}列解析异常，数据为:{}", excelDataConvertException.getRowIndex(),
                    excelDataConvertException.getColumnIndex(), excelDataConvertException.getCellData());
        }
        throw exception;
    }

    @Override
    public void invoke(EmsDataDTO emsDataDTO, AnalysisContext analysisContext) {
        try {
            log.info("解析到一条数据:{}", emsDataDTO.toString());

            // 添加到缓冲区
            buffer.add(emsDataDTO);

            // 达到批次大小后发送并清空缓冲区
            if (buffer.size() >= BATCH_SIZE) {
                sendBatch();
            }
        } catch (Exception e) {
            log.error("解析单条数据失败，数据内容: {}，异常信息: ", emsDataDTO, e);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

        // 所有数据解析完成后，发送剩余的数据
        if (!buffer.isEmpty()) {
            sendBatch();
        }

    }

    /**
     * 发送一批数据到 Disruptor
     */
    private void sendBatch() {
        log.info("发送一批数据，共 {} 条", buffer.size());
        emsDisruptorProducer.pushData(buffer);
        buffer.clear(); // 清空缓冲区
    }

}
